#include "AudioSwitcher.h"

#include <QtCore/QDebug>

AudioSwitcher::AudioSwitcher(QObject *parent)
	: QObject(parent)
{
}

AudioSwitcher::~AudioSwitcher()
{

}

QMap<QString, QString> AudioSwitcher::GetAudioPlaybackDevices()
{
	return EnumAudioPlaybackDevice();
}

HRESULT AudioSwitcher::SetDefaultNextAudioPlaybackDevice(ERole role)
{
	HRESULT hr = S_FALSE;
	QString default = GetDefaultAudioEndpoint(role);
	QMap<QString, QString> devices = EnumAudioPlaybackDevice();

	QMapIterator<QString, QString> i(devices);
	while (i.hasNext())
	{
		i.next();
		if(i.key()==default)
		{
			if(i.hasNext())
			{
				i.next();
				hr = SetDefaultAudioPlaybackDevice(i.key(),role);
			}
			else
			{
				hr = SetDefaultAudioPlaybackDevice(devices.firstKey(),role);
			}
			break;
		}
	}
	return hr;
}

void AudioSwitcher::SetDefaultAudioPlaybackDevice(int index, ERole role)
{	

	if(role==eCommunications)
		EnumAudioPlaybackDevice(-1,index);
	else if(role==eMultimedia)
		EnumAudioPlaybackDevice(index,-1);
	else EnumAudioPlaybackDevice(index,index);
}
HRESULT AudioSwitcher::SetDefaultAudioPlaybackDevice(QString devID, ERole role)
{
	return SetDefaultAudioPlaybackDevice(devID.utf16(), role);
}
HRESULT AudioSwitcher::SetDefaultAudioPlaybackDevice(LPCWSTR devID, ERole role)
{	
	IPolicyConfigVista *pPolicyConfig;

	HRESULT hr = CoCreateInstance(__uuidof(CPolicyConfigVistaClient), 
		NULL, CLSCTX_ALL, __uuidof(IPolicyConfigVista), (LPVOID *)&pPolicyConfig);
	if (SUCCEEDED(hr))
	{
		hr = pPolicyConfig->SetDefaultEndpoint(devID, role);
		pPolicyConfig->Release();
	}
	return hr;
}

QString AudioSwitcher::GetDefaultAudioEndpoint(ERole role)
{
	LPWSTR defaultDevice = NULL;

	IMMDeviceEnumerator *pEnum = NULL;
	// Create a multimedia device enumerator.
	HRESULT hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL,
		CLSCTX_ALL, __uuidof(IMMDeviceEnumerator), (void**)&pEnum);
	if (SUCCEEDED(hr))
	{
		IMMDevice *pDevice;
		// Enumerate the output devices.
		hr = pEnum->GetDefaultAudioEndpoint(eRender, role, &pDevice);
		if (SUCCEEDED(hr))
		{
			hr = pDevice->GetId(&defaultDevice);

			pDevice->Release();
		}
		pEnum->Release();
	}
	return QString::fromUtf16(defaultDevice);
}

QString AudioSwitcher::GetDeviceName(QString wstrID)
{
	QString name;
	IMMDeviceEnumerator *pEnum = NULL;
	// Create a multimedia device enumerator.
	HRESULT hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL,
		CLSCTX_ALL, __uuidof(IMMDeviceEnumerator), (void**)&pEnum);
	if (SUCCEEDED(hr))
	{
		IMMDevice *pDevice;
		pEnum->GetDevice(wstrID.utf16(),&pDevice);
		name = GetDeviceName(pDevice);

	}
	return name;
}

QString AudioSwitcher::GetDeviceName(IMMDevice *pDevice)
{
	QString name;
	IPropertyStore *pStore;
	HRESULT hr = pDevice->OpenPropertyStore(STGM_READ, &pStore);
	if (SUCCEEDED(hr))
	{
		PROPVARIANT friendlyName;
		PropVariantInit(&friendlyName);
		hr = pStore->GetValue(PKEY_Device_FriendlyName, &friendlyName);
		if (SUCCEEDED(hr))
		{
			name = QString::fromUtf16(friendlyName.pwszVal);
			PropVariantClear(&friendlyName);
		}
		pStore->Release();
	}
	return name;
}

QMap<QString, QString> AudioSwitcher::EnumAudioPlaybackDevice(int multimedia,int communications)
{
	QMap<QString, QString> devices;

	IMMDeviceEnumerator *pEnum = NULL;
	// Create a multimedia device enumerator.
	HRESULT hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL,
		CLSCTX_ALL, __uuidof(IMMDeviceEnumerator), (void**)&pEnum);
	if (SUCCEEDED(hr))
	{
		IMMDeviceCollection *pDevices;
		// Enumerate the output devices.
		hr = pEnum->EnumAudioEndpoints(eRender, DEVICE_STATE_ACTIVE, &pDevices);
		if (SUCCEEDED(hr))
		{
			UINT count;
			pDevices->GetCount(&count);
			if (SUCCEEDED(hr))
			{
				for (int i = 0; i < count; i++)
				{
					IMMDevice *pDevice;
					hr = pDevices->Item(i, &pDevice);
					if (SUCCEEDED(hr))
					{
						LPWSTR wstrID = NULL;
						hr = pDevice->GetId(&wstrID);
						if (SUCCEEDED(hr))
						{
							devices.insert(QString::fromUtf16(wstrID), GetDeviceName(pDevice));
							if (i == communications) SetDefaultAudioPlaybackDevice(wstrID, eMultimedia);
							if (i == multimedia) SetDefaultAudioPlaybackDevice(wstrID, eCommunications);
						}
						pDevice->Release();
					}
				}
			}
			pDevices->Release();
		}
		pEnum->Release();
	}
	return devices;
}
